package main

import (
	"log"
	"net"
	"sync"

	"github.com/golang/glog"
	"github.com/gorilla/websocket"
	"golang.org/x/sys/unix"
)

func main() {
	var wg sync.WaitGroup
	wg.Add(2)

	// CAN配置
	socket, err := unix.Socket(unix.AF_CAN, unix.SOCK_RAW, unix.CAN_RAW)
	if err != nil {
		log.Fatalf("创建CAN socket失败: %v", err)
	}
	defer unix.Close(socket)

	ifindex := 0 // 根据实际情况设置CAN接口索引
	addr := &unix.SockaddrCAN{Ifindex: ifindex}
	if err := unix.Bind(socket, addr); err != nil {
		log.Fatalf("绑定CAN接口失败: %v", err)
	}

	// TCP服务器配置
	tcpAddr := ":8080" // 监听端口

	// 启动TCP服务器
	listener, err := net.Listen("tcp", tcpAddr)
	if err != nil {
		log.Fatalf("启动TCP服务器失败: %v", err)
	}
	defer listener.Close()
	log.Printf("TCP服务器已启动，监听端口 %s", tcpAddr)

	// CAN到TCP的转发
	go func() {
		defer wg.Done()
		buf := make([]byte, 16) // CAN帧通常较小
		var tcpConnections []net.Conn
		
		for {
			n, err := unix.Read(socket, buf)
			if err != nil {
				log.Printf("CAN读取错误: %v", err)
				continue
			}

			if n > 0 {
				data := buf[:n]
				log.Printf("从CAN接收到数据: % X", data)
				
				// 转发给所有TCP客户端
				for i := 0; i < len(tcpConnections); i++ {
					conn := tcpConnections[i]
					if _, err := conn.Write(data); err != nil {
						log.Printf("TCP写入错误: %v", err)
						conn.Close()
						tcpConnections = append(tcpConnections[:i], tcpConnections[i+1:]...)
						i--
					}
				}
			}
		}
	}()

	// TCP到CAN的转发
	go func() {
		defer wg.Done()
		var tcpConnections []net.Conn
		
		for {
			conn, err := listener.Accept()
			if err != nil {
				log.Printf("TCP连接错误: %v", err)
				continue
			}
			log.Printf("新的TCP连接: %s", conn.RemoteAddr())
			
			// 保存TCP连接用于转发
			tcpConnections = append(tcpConnections, conn)
			go handleTCPConnection(conn, socket)
		}
	}()

	wg.Wait()
}

func handleTCPConnection(conn net.Conn, socket int) {
	defer conn.Close()
	buf := make([]byte, 16)

	for {
		n, err := conn.Read(buf)
		if err != nil {
			log.Printf("TCP读取错误: %v", err)
			return
		}

		if n > 0 {
			data := buf[:n]
			log.Printf("从TCP接收到数据: % X", data)
			// 转发到CAN
			_, err := unix.Write(socket, data)
			if err != nil {
				log.Printf("CAN写入错误: %v", err)
				return
			}
		}
	}
}